#include<iostream>
#include<assert.h>
#include<string.h>
using namespace std;

template<class T>
class Stack
{
public:
    Stack(int capacity = 0)//防止传进来负数，利用判断进行初始化，不使用初始化列表
        :_a(NULL)
        ,_top(0)
        ,_capacity(0)
    {
        if (capacity > 0)
        {
            _a = new T[capacity];
            _capacity = capacity;
        }
    }
    ~Stack()
    {
        delete[] _a;
        _a = NULL;
        _top = _capacity = 0;
    }
    void Push(const T& x);
    const T& Top()//传引用返回的话一定要注意加上const，否则外界可以随意修改私有成员了
    {
        assert(_top > 0);
        return _a[_top - 1];
    }
    void Pop()
    {
        assert(_top > 0);
        --_top;
    }
private:
    T* _a;//利用数组存放
    size_t _top;//储存当前数据个数
    size_t _capacity;//当前的容量
};
void Stack<T>::Push(const T& x)
{
    if (_top == _capacity)//没有内存或者满了
    {
        size_t newcapacity = _capacity == 0 ? 4 : _capacity * 2;
        //手动扩展 c语言里面是使用realloc，此处c++使用new出一个大的空间，在将原有数据拷贝进去
        T* temp = new T[newcapacity];
        if (_a)//防止原本空的被拷贝进去了
        {
            memcpy(temp, _a, sizeof(T)*_top);
            delete[] _a;
        }
        _a = temp;
        _capacity = newcapacity;
    }
    _a[_top++] = x;
}

int main()
{
    Stack<int> a;
    Stack<int> b(3);
    Stack<char> c(2);
    b.Push(1);
    b.Push(2);
    b.Push(3);
    b.Push(4);
    c.Push('a');
    c.Push('b');
    c.Push('c');
    return 0;
}
